home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.1 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #include "Memory.h"
- #include "MemoryCalls.h"
- #include "Error.h"
- void TotalRedrawVIC(void);
-
-
- #define FastDraw(a, b, c) \
- { \
- thisLine=(char**)&(lineStart[(word)((a)<<3)]); \
- theseDefs=(char*)(VICCharDefs+(word)((c)<<3)); \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- *(*thisLine++ + b)=*theseDefs++; \
- }
-
-
-
- WindowPtr VICWind;
- byte VICText[1024], VICRegister[0x2f];
- word VICAddrBase, VICScreenPage, VICCharBase;
- byte VICBank, *VICCharDefs;
- byte *lineStart[200];
-
- Rect fullRect, leftRect, rightRect, topRect, botRect, spr;
- BitMap saveMap, spriteMap, VICMap, fullMap;
-
- GrafPtr spriteGraf;
-
- byte CreateOffscreenBitMap(GrafPtr *newOffscreen, Rect *inBounds)
- {
- GrafPtr savePort, newPort;
-
- GetPort(&savePort);
- newPort = (GrafPtr)GetMemory(sizeof(GrafPort));
-
- OpenPort(newPort);
-
- newPort->portRect = *inBounds;
- newPort->portBits.bounds = *inBounds;
- RectRgn(newPort->clipRgn, inBounds);
- RectRgn(newPort->visRgn, inBounds);
-
- newPort->portBits.rowBytes =
- ((inBounds->right - inBounds->left + 15) >> 4) << 1;
- newPort->portBits.baseAddr = (Ptr)
- GetMemory(newPort->portBits.rowBytes*(long)(inBounds->bottom-inBounds->top));
-
- if(MemError() != noErr) {
- SetPort(savePort);
- ClosePort(newPort);
- DisposPtr((Ptr)newPort);
- return 0;}
-
- EraseRect(inBounds);
- *newOffscreen = newPort;
- SetPort(savePort);
- return 1;
- }
-
- Ptr NewBitMap(BitMap *theBits, Rect *rp)
- {
- theBits->rowBytes=((rp->right-rp->left+15)/16)*2;
- theBits->baseAddr=(Ptr)GetMemory(theBits->rowBytes*(rp->bottom-rp->top));
- theBits->bounds=*rp;
- return(theBits->baseAddr);
- }
-
- int VICInitialize()
- {
- int row, col, chr;
-
- row=col=0;
- SetRect(&fullRect,0,0,320,200);
- SetRect(&leftRect,0,0,7,200);
- SetRect(&rightRect,320-8,0,320,200);
- SetRect(&topRect,0,0,320,4);
- SetRect(&botRect,0,200-4,320,200);
- SetRect(&spr,0,0,24,21);
- VICWind=GetNewWindow(128,nil,(void *)-1L);
- if (VICWind==nil) return(kWindowMissing);
- ShowWindow(VICWind);
- SetPort(VICWind);
- SelectWindow(VICWind);
- if (NewBitMap(&spriteMap, &spr)==0) return kOutOfMemory;
- if (NewBitMap(&VICMap, &fullRect)==0) return kOutOfMemory;
- if (NewBitMap(&fullMap, &fullRect)==0) return kOutOfMemory;
-
- for (row=0; row<200; row++)
- lineStart[row]=(byte *)VICMap.baseAddr+40*row;
-
- return(kNoError);
- }
-
- void VICAddrAdjust()
- {
- VICBank=(RAM[0xdd00]&3)^3;
- VICAddrBase=VICBank*16384;
- VICScreenPage=((RAM[0xd018]&0xf0)>>4)*0x0400+VICAddrBase;
- VICCharBase=((RAM[0xd018]&0x0e)*1024);
- if ((VICBank==1)||(VICBank==3))
- VICCharDefs=RAM+(VICAddrBase+VICCharBase);
- else
- if (VICCharBase==4096) VICCharDefs=charROM;
- else if (VICCharBase==6144) VICCharDefs=charROM+0x0800;
- else VICCharDefs=RAM+(VICAddrBase+VICCharBase);
- }
-
- byte NotSameVIC()
- {
- register byte addr;
-
- for (addr=0; addr<0x2f; addr++) {
- if (addr==0x11)
- { if ((RAM[0xd011]&127)!=(VICRegister[0x11]&127))
- return 1;}
- else if (addr==0x12);
- else if (RAM[0xd000+addr]!=VICRegister[addr]) return 1; }
- return 0;
- }
-
- void DrawSprites()
- {
- byte spriteNum, row, *spb0, *spb1, *spb2;
- word xpos, ypos, addr0, addr1, addr2;
- Rect t;
-
- BlockMove(VICMap.baseAddr, fullMap.baseAddr, GetPtrSize(VICMap.baseAddr));
- saveMap = qd.thePort->portBits;
- SetPortBits(&spriteMap);
- for (spriteNum=0; spriteNum<8; spriteNum++)
- if (VICRegister[0x15]&(1<<spriteNum)) {
- xpos=VICRegister[0x00+spriteNum*2]-24;
- ypos=VICRegister[0x01+spriteNum*2]-50;
- xpos += (VICRegister[0x10]&(1<<spriteNum))?256:0;
- t.top=ypos;t.left=xpos;
- t.right=t.left+24+((VICRegister[0x1d]&(1<<spriteNum))?24:0);
- t.bottom=t.top+21+((VICRegister[0x17]&(1<<spriteNum))?21:0);
- addr0 = VICAddrBase+RAM[VICScreenPage+1016+spriteNum]*64;
- addr1= addr0+1; addr2=addr0+2;
- spb0=(byte *)spriteMap.baseAddr; spb1=spb0+1; spb2=spb0+2;
- for (row=0; row<21; row++) {
- spb0[row<<2]=RAM[addr0+row*3];
- spb1[row<<2]=RAM[addr1+row*3];
- spb2[row<<2]=RAM[addr2+row*3]; }
- CopyBits(&spriteMap,&fullMap,&spr,&t,srcOr,nil); }
- SetPortBits(&saveMap);
- SetPort(VICWind);
- }
- /*
- void ScrollScreen()
- {
- word xscroll, yscroll;
-
- xscroll=VICRegister[0x16]&7; yscroll=(VICRegister[0x11]&7)-3;
- if (yscroll>0)
- BlockMove(lineStart[0],lineStart[yscroll],(320/8)*(200-yscroll));
- else if (yscroll<0)
- BlockMove(line
- */
- void DrawTextScreen(byte total)
- {
- word chr;
- byte row, col;
- register char **thisLine;
- register char *theseDefs;
-
- row=col=0;
- saveMap=qd.thePort->portBits;
- SetPortBits(&VICMap);
- /* SetOrigin(-(VICRegister[0x16]&7),-((VICRegister[0x11]&7)-3));*/
- if (VICRegister[0x11]&32) {
- VICCharDefs=RAM+VICAddrBase+((VICRegister[0x18]&8)?8192:0);
- for (chr=0;chr<1000;chr++) {
- FastDraw(row,col,chr);
- col++;if (col>39) {col=0;row++;} }
- }
- else {
- if (total)
- for (chr=0;chr<1000;chr++) {
- FastDraw(row,col,RAM[chr+VICScreenPage]);
- VICText[chr]=RAM[chr+VICScreenPage];
- col++;if (col>39) {col=0;row++;} }
- else
- for (chr=0;chr<1000;chr++) {
- if (VICText[chr]!=RAM[chr+VICScreenPage]) {
- FastDraw(row,col,RAM[chr+VICScreenPage]);
- VICText[chr]=RAM[chr+VICScreenPage]; }
- col++;if (col>39) {col=0;row++;} } }
- /* SetOrigin(0,0);*/
- SetPortBits(&saveMap);
- /* ScrollRect(&fullRect, VICRegister[0x16]&7,(VICRegister[0x11]&7)-3,nil);*/
- }
-
- void DrawBorders()
- {
- saveMap=qd.thePort->portBits;
- SetPortBits(&VICMap);
- if (VICRegister[0x16]&8);else {FillRect(&leftRect,(PatPtr)&qd.black);FillRect(&rightRect,(PatPtr)&black);}
- if (VICRegister[0x11]&8);else {FillRect(&botRect,(PatPtr)&black);FillRect(&topRect,(PatPtr)&black);}
- SetPortBits(&saveMap);
- }
-
- void CopyTextToScreen()
- {
- SetPort(VICWind);
- CopyBits(&VICMap,&(VICWind->portBits),&fullRect,&fullRect,srcCopy,nil);
- }
-
- void CopySpritesToScreen()
- {
- SetPort(VICWind);
- CopyBits(&fullMap,&(VICWind->portBits),&fullRect,&fullRect,srcCopy,nil);
- }
-
- void BlankScreen()
- {
- saveMap = qd.thePort->portBits;
- SetPortBits(&VICMap);
- FillRect(&fullRect, (PatPtr)&qd.gray);
- SetPortBits(&saveMap);
- CopyTextToScreen();
- return;
- }
-
- void RedrawVIC()
- {
- if (NotSameVIC()) { TotalRedrawVIC(); return; }
- VICAddrAdjust();
- SetPort(VICWind);
- if (VICRegister[0x11]&16); else { BlankScreen(); return;}
- DrawTextScreen(0);
- DrawBorders();
- if (VICRegister[0x15]) { DrawSprites(); CopySpritesToScreen();}
- else CopyTextToScreen();
- }
-
- void TotalRedrawVIC()
- {
- register byte addr;
-
- for (addr=0; addr<0x2f; addr++) VICRegister[addr]=RAM[0xd000+addr];
- VICAddrAdjust();
- SetPort(VICWind);
- if (VICRegister[0x11]&16); else { BlankScreen(); return;}
- DrawTextScreen(1);
- DrawBorders();
- if (VICRegister[0x15]) { DrawSprites(); CopySpritesToScreen();}
- else CopyTextToScreen();
- }
-